package com.offcn.pay.controller;

import com.alibaba.fastjson.JSON;
import com.offcn.entity.Result;
import com.offcn.entity.StatusCode;
import com.offcn.order.feign.OrderFeign;
import com.offcn.order.pojo.PayLog;
import com.offcn.pay.service.AliPayService;
import com.offcn.utils.IdWorker;
import com.offcn.utils.TokenDecode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailParseException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/pay")
public class PayController {

    @Autowired
    private AliPayService payService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping("/notify/url")
    public String getPayResult(HttpServletRequest request) {
        System.out.println("支付宝回调的方法");
        HashMap<String, String> requestMap = new HashMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String paramterName = parameterNames.nextElement();
            requestMap.put(paramterName,request.getParameter(paramterName));
        }
        // exchange=com.seckill.pay&routingKey=seckill&username=xiaobai
        String body = requestMap.get("body");
        String[] keyAndValue = body.split("&");
        for (String kv : keyAndValue) {
            String[] kvs = kv.split("=");
            requestMap.put(kvs[0],kvs[1]);
        }

        // 通过消息中间件发送消息
        rabbitTemplate.convertAndSend(requestMap.get("exchange"),requestMap.get("routingKey"),JSON.toJSONString(requestMap));

        return "支付回调方法完成";
    }

    @GetMapping("/createQrCode")
    public Result createQrCode(){
        // 获取令牌
        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String token = details.getTokenValue();
        // 解析令牌
        String username = TokenDecode.getUsername(token);
        // 生成支付id
        String payLogStr = (String)stringRedisTemplate.boundHashOps("payLog").get(username);
        PayLog payLog = JSON.parseObject(payLogStr, PayLog.class);
        Map map = payService.createQrCode(payLog.getOutTradeNo() + "", payLog.getTotalFee() + "");
        return new Result<>(true,StatusCode.OK,map,"获取支付二维码成功");
    }

    @RequestMapping("/createSeckillQrCode")
    public Result<Map> createSeckillQrCode(@RequestBody Map parameters) {
        // 获取令牌
        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
        String token = details.getTokenValue();
        // 解析令牌
        String username = TokenDecode.getUsername(token);
        parameters.put("username",username);
        Map map = payService.createSeckillQrCode(parameters);
        return new Result<>(true,StatusCode.OK,map,"二维码创建成功");
    }

    @RequestMapping("/queryPayStatus")
    public Result queryPayStatus(String out_trade_no){
        int num = 0;
        while (true) {
            Map<String, String> resultMap = payService.queryPayStatus(out_trade_no);
            if (resultMap == null) {
                return new Result(false, StatusCode.ERROR,"支付失败");
            }
            /**
             * WAIT_BUYER_PAY（交易创建，等待买家付款）、
             * TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
             * TRADE_SUCCESS（交易支付成功）、
             * TRADE_FINISHED（交易结束，不可退款）
             */
            if (resultMap.get("status") != null && resultMap.get("status").equals("WAIT_BUYER_PAY")) {
                System.out.println("订单正在等待支付中");
            }

            if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_SUCCESS")) {
                System.out.println("支付成功");
                // 完善 支付数据 => tb_order 和 tb_pay_log
                orderFeign.updateOrderStatus(resultMap.get("out_trade_no"),resultMap.get("trade_no"));
                return new Result(true,StatusCode.OK,"支付成功");
            }

//            if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_CLOSED")) {
//                System.out.println("支付超时");;
//                return new Result(false,StatusCode.ERROR,"支付超时");
//            }

            try {
                Thread.sleep(3000); //4秒钟该方法执行一次
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            num++;
            if (num >= 20) {  // 执行20次，就是1分钟
                System.out.println("支付超时");;
                return new Result(false,StatusCode.ERROR,"支付超时");
            }

        }
    }

    @RequestMapping("/queryPayStatus2")
    public Result queryPayStatus2(String out_trade_no){

        //while (true) {
            Map<String, String> resultMap = payService.queryPayStatus(out_trade_no);
            if (resultMap == null) {
                return new Result(false, StatusCode.LOGINERROR,"支付失败");
            }
            /**
             * WAIT_BUYER_PAY（交易创建，等待买家付款）、
             * TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
             * TRADE_SUCCESS（交易支付成功）、
             * TRADE_FINISHED（交易结束，不可退款）
             */
            if (resultMap.get("status") != null && resultMap.get("status").equals("WAIT_BUYER_PAY")) {
                System.out.println("订单正在等待支付中");
            }

            if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_SUCCESS")) {
                System.out.println("支付成功");
                // 完善 支付数据 => tb_order 和 tb_pay_log
                orderFeign.updateOrderStatus(resultMap.get("out_trade_no"),resultMap.get("trade_no"));
                return new Result(true,StatusCode.OK,"支付成功");
            }

        if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_CLOSED")) {
            System.out.println("未付款交易超时关闭，或支付完成后全额退款");

            return new Result(true,StatusCode.ACCESSERROR,"支付关闭");
        }

        if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_FINISHED")) {
            System.out.println("交易结束，不可退款");

            return new Result(true,StatusCode.REMOTEERROR,"交易结束，不可退款");
        }

//            if (resultMap.get("status") != null && resultMap.get("status").equals("TRADE_CLOSED")) {
//                System.out.println("支付超时");;
//                return new Result(false,StatusCode.ERROR,"支付超时");
//            }


                System.out.println("支付超时");;
                return new Result(false,StatusCode.ERROR,"支付超时");


       // }
    }
}
